#include "ofxSimplePhysics.h"
#include "stdio.h"

//--------------------------------------------------------------
void ofxSimplePhysics::setup(){
//Value given to the deceleration
    dv=0.0005;

//Assign adds new values to an array, in this case 2 new objects from the class thing

//Value given to the gravity
    gravity=0.06;


}

//create function
void ofxSimplePhysics::createThings(int count) {

//duplicates the class
    Thing thing;

//makes as many classes as requested
    things.assign(count,thing);

//Gives each class in the array random starting values
    for(int i=0;i<count;i++)
    {
		things[i].vy=ofRandom(10.0,18.5);
		things[i].vx=ofRandom(10.0,18.5);
		things[i].weight=int(ofRandom(50,200));
		things[i].y=int(ofRandom(50,550));
		things[i].x=int(ofRandom(50,350));
		things[i].degrees=0;
    }
}

//--------------------------------------------------------------
void ofxSimplePhysics::update(){
//variables distance between entities
    float distX;
    float distY;
    float dist;

//First loop to add calculations to each individual entity
    for(int i=0;i<things.size();i++)
    {
    //Second loop needed to check distances between 2 entities
        for (int j=0;j<things.size();j++) {
        //this check disables the script in case the first entity is used for both 'i' and 'j'
            if (j!=i) {
            //calculates the distances between all the entities on the screen
                distX = things[i].x - things[j].x;
                distY = things[i].y - things[j].y;

            //basic A^2 + B^2 = C^2
                dist = sqrt((distX*distX) + (distY*distY));

            //IMPORTANT CHECK, whether the calculated distance is smaller then the radius of both entities combined,
                if (dist <= (things[i].weight / 2) + (things[j].weight / 2)) { //checks is the distance between the entities equals the sum of the radii
                    things[i].vx += (things[i].vx * (things[i].weight/200)) + (distX/(things[i].weight) * (200-things[i].weight)/200);
                //Looks at the difference in weight between the colliding entities. Depending on the size of the difference the speed of the entities is changed
                    things[i].vy += (things[i].vy * (things[i].weight/200)) + (distY/(things[i].weight) * (200-things[i].weight)/200);
                //creates deceleration
                    things[i].vx /= 1 + (things[i].weight/100);
                    things[i].vy /= 1 + (things[i].weight/100);
                }
            }
        }

    //Creates entity movement
    //yBal+=vyBal equals yBal = yBal + vyBal
        things[i].y+=things[i].vy;
        things[i].x+=things[i].vx;

    //adds a value to the rotation
        things[i].degrees += things[i].vy;

    //Creates deceleration, in which the speed of the entity is reversed
        things[i].vy /= 1 + dv * (things[i].weight);
        things[i].vx /= 1 + dv * (things[i].weight);

    //gravity
        things[i].vx+=0.006;

    //Following scripts allow the entity to bounce off the walls
    //As soon as the entity bounces off the wall a sound is played and the speed of the entity slows down slightly
        if (things[i].y>800-things[i].weight/2)
        {
            things[i].vy*=-1;
			//When the entity bounces, it is set 2 pixels from the screen to ensure problems won't occur
            things[i].y = 798 - things[i].weight/2;
            //SoundE.play();
        }

        if (things[i].x>600-things[i].weight/2)
        {
			//When the entity hits the floor, friction
            things[i].vx/=1+(things[i].weight/200);
            things[i].vy/=1+(things[i].weight/200);

            things[i].vx*=-1;
			//friction also used in a sum
            if (things[i].vy >0) {
                things[i].vy-= 0.001;
            } else {
                things[i].vy+= 0.001;
            }

			//holds the entity in place whenenever it reaches a certain slow speed
            if (things[i].vx<=0.3 && things[i].vx >= -0.3){
                things[i].vx = 0;
                things[i].x= 600-things[i].weight/2;
            }

            else {
                things[i].x=598-things[i].weight/2;
                things[i].vx+=0.1;
            }
            //SoundS.play();

        }

        if (things[i].y<0+things[i].weight/2)
        {
            things[i].vy*=-1;
            things[i].y = 2+things[i].weight/2;
            //SoundW.play();
        }

        if (things[i].x<0+things[i].weight/2)
        {
            things[i].vx*=-1;
            things[i].x = 2+things[i].weight/2;
            //SoundN.play();
        }

    }
}

//--------------------------------------------------------------
void ofxSimplePhysics::draw(){
    //Simple loop to give each entity a basic draw
    for(int i=0;i<things.size();i++) {
        ofCircle(things[i].x, things[i].y,10);
    }
}

